<!--  -->
<template>
  <div class="app-container">
    <!-- START 卡片视图 START -->
    <el-card style="margin-bottom: 10px;">
      <!-- START添加和展开/折叠按扭区域 START -->
      <el-row :gutter="10">
        <el-col :span="5">
          <el-input
              v-model="menuName"
              size="small"
              placeholder="请输入菜单名称"
              clearable
              @clear="getMenusList"
            />
          </el-col>
          <el-col :span="2">
            <el-button
              icon="el-icon-search"
              type="primary"
              size="mini"
              @click="getMenus"
            >搜索</el-button>
        </el-col>
        <el-col :span="6">
          <el-button type="primary" plain size="mini" icon="el-icon-plus" @click="openRightDialog">新增</el-button>
          <el-button type="info" plain size="mini" icon="el-icon-sort" @click="toggleExpandAll">展开/折叠</el-button>
        </el-col>
      </el-row>
      <!--  END 添加和展开/折叠按扭区域 END -->
    </el-card>
    <!-- END 卡片视图 END -->

    <!-- START 权限列表区域 START -->
    <el-card>
      <el-table
        v-loading="listLoading"
        :data="menuList"
        style="width: 100%; margin-bottom: 20px"
        row-key="id"
        :stripe="true"
        :default-expand-all="isExpandAll"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"

      >
        <el-table-column label="权限名称" width="240px" align="left">
          <template slot-scope="{row}">
            <span>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column label="请求路径" width="240px" align="center">
          <template slot-scope="{row}">
            <span>{{ row.url }}</span>
          </template>
        </el-table-column>
        <el-table-column label="组件路径" width="160px" align="center">
          <template slot-scope="{row}">
            <span>{{ row.path }}</span>
          </template>
        </el-table-column>
        <el-table-column label="组件名称" width="180px" align="center">
          <template slot-scope="{row}">
            <span v-if="row.component != null">{{ row.component }}.vue</span>
            <span v-else />
          </template>
        </el-table-column>
        <el-table-column label="图标" width="80px" align="center">
          <template slot-scope="{row}">
            <span :class="row.iconCls" />
<!-- 因为小图标来自两个不同地方，一个是Element-ui，另一个是本地，所以我们将@/layout/components/Sidebar/Item.vue组件导入进来，使用这个组件来显示小图标，这个Item.vue组件中对这两个不同位置的小图标进行了判断-->
<item :icon="row.iconCls"></item>
          </template>
        </el-table-column>
        <!-- 菜单类别：menuLevel字段，1、代表菜单  2、按扭-->
        <el-table-column label="菜单类别" width="110px" align="center">
          <template slot-scope="{row}">
            <span v-if="row.menuLevel == 3">按扭</span>
            <span v-else>菜单</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200px" align="center">
          <!-- 使用作用域插槽的形式为[权限等级]列自定义内容，使用scope来接收所有的数据 -->
          <template slot-scope="scope">
            <!-- 编辑按扭 -->
            <el-button
              icon="el-icon-edit"
              type="primary"
              size="mini"
              plain
              round
              @click="showEditDialog(scope.row.id)"
            >编辑</el-button>
            <!-- 删除按扭 -->
            <el-button
              icon="el-icon-delete"
              type="danger"
              size="mini"
              plain
              round
              @click="delRightById(scope.row.id)"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- END 权限列表区域 END-->

    <!-- START 添加菜单权限对话框 START -->
    <el-dialog
      :title="textMap[dialogStatus]"
      :visible.sync="addRightDialogVisible"
      width="40%">
      <el-form ref="addFormRef" :rules="addFormRules" :model="addForm" label-position="left" label-width="80px" style="width: 550px; margin-left:15px;">
        <el-form-item label="上级菜单" prop="name">
            <tree-select
              ref="treeRef"
              :data="treeMenuList"
              :default-props="defaultProps"
              :node-key="nodeKey"
              @popoverHide="popoverHide"
              :checked-keys="defaultCheckedKeys"
            />
        </el-form-item>

        <el-row :gutter="40">
          <el-col :span="16">
            <el-form-item label="菜单等级" prop="menuLevel">
              <el-radio-group v-model="addForm.menuLevel">
                <el-radio :label="1">一级</el-radio>
                <el-radio :label="2">二级</el-radio>
                <el-radio :label="3">三级</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="菜单状态" prop="enabled">
              <el-switch v-model="addForm.enabled" />
            </el-form-item>
          </el-col>
      </el-row>
      <el-form-item label="菜单图标" prop="iconCls">
        <el-popover
          placement="bottom-start"
          width="460"
          trigger="click"
          @show="$refs['iconSelect'].reset()"
        >
          <IconSelect ref="iconSelect" @selected="selected" />
          <el-input slot="reference" v-model="addForm.iconCls" placeholder="点击选择图标" readonly>
            <svg-icon
              v-if="addForm.iconCls"
              slot="prefix"
              :icon-class="addForm.iconCls"
              class="el-input__icon"
              style="height: 32px;width: 16px;"
            />
            <i v-else slot="prefix" class="el-icon-search el-input__icon" />
          </el-input>
        </el-popover>
      </el-form-item>
      <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="name">
              <el-input v-model="addForm.name" placeholder="请输入菜单名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="权限路径" prop="url">
              <el-input v-model="addForm.url" placeholder="请输入权限路径" />
            </el-form-item>
          </el-col>
      </el-row>
      <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="路由地址" prop="path">
              <el-input v-model="addForm.path" placeholder="请输入路由地址" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="组件地址" prop="url">
              <el-input v-model="addForm.component" placeholder="请输入组件地址" />
            </el-form-item>
          </el-col>
      </el-row>

      </el-form>

      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelEvent() ">取 消</el-button>
        <el-button type="primary" @click="dialogStatus==='create'?insertData():updateData()">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
// 这里可以导入其他文件（比如：组件，工具js，第三方插件js，json文件，图片文件等等）
// 例如：import 《组件名称》 from '《组件路径》';
// Item.vue组件用于显示小图标
import Item from '@/layout/components/Sidebar/Item'
import TreeSelect from '@/components/TreeSelect'
import IconSelect from '@/components/IconSelect'
import { getAllMenuList,saveMenu,findByMenuId,updateMenu,delMenuById } from '@/api/menu'
export default {
// import引入的组件需要注入到对象中才能使用
  components: {
    Item,
    TreeSelect,
    IconSelect
  },
  data() {
    // 这里存放数据
    return {
      // 菜单列表
      menuList: [],
      // true则会显示正在加载的图标
      listLoading: true,
      // 展开/折叠通过下面属性来控制
      isExpandAll: false,
      //过滤条件 菜单名称
      menuName:'',

      // 用于控制[添加菜单]对话框的显示与隐藏，true表示显示,false表示隐藏
      addRightDialogVisible: false,
      // 因为添加和编辑用户共用一个弹出窗口，通过dialogStatus来动态设置弹出窗口的标题。
      dialogStatus: '',
      textMap: {
        create: '添加菜单',
        update: '编辑菜单'
      },
      addForm: {
        id: undefined,
        url: '',
        path: null,
        component: null,
        name: '',
        iconCls: '',
        enabled: 1,
        menuLevel: 1,
        parentId: 0
      },

      // 添加菜单对话框中，上级菜单下拉框的数据绑定到如下变量中
      treeMenuList: [],
      defaultProps: {
        children: 'children', // 树形控件的子节点
        label: 'name' // 以权限名作为树形控件的显示值
      },
      nodeKey: 'id', // 以权限编号作为当前树形控件中节点的key

      defaultCheckedKeys:[]
    }
  },
  // 生命周期 - 挂载完成（可以访问DOM元素）
  mounted() {
    // 在窗口加载事件中，直接调用getMenusList()查询出菜单列表信息
    this.getMenusList()
  },
  watch:{
    addForm:function(){
      this.$nextTick(function(){
        this.$refs["treeRef"].$emit("updateCheckedKey");
      })
    }
  },

  // 方法集合
  methods: {
    // 查询权限列表
    getMenusList() {
      // true时，表格中就会出现正在加载图标
      this.listLoading = true
      getAllMenuList().then((res) => {
        // false时，正在加载图标就会消失
        this.listLoading = false
        this.menuList = res

        //清空
        this.treeMenuList=[];

        // 往this.treeMenuList数组中第一位置添加数据
        this.treeMenuList.push({
          name: '主目录',
          id: 1,
          children: this.menuList
        })

      }).catch((err) => {
        console.log(err)
      })
    },
    //条件查询
    getMenus(){
      if(this.menuName!=''){
        const menus = []
        this.queryMenu(this.menuName,this.menuList,menus);
        this.menuList=menus;
      }else{
        this.getMenusList();
      }
    },
    // menuName为菜单名称查询条件， data为菜单列表  menus保存按菜单名称模糊查询得到的数据
    queryMenu(menuName, data, menus) {
      data.forEach((menu) => {
        if (menu.name.indexOf(menuName) !== -1) {
          menus.push(menu)
        } else {
          if (menu.children != null && menu.children.length !== 0) {
            this.queryMenu(menuName, menu.children, menus)
          }
        }
      })
    },
    openRightDialog(){
      //1.显示模态框
      this.addRightDialogVisible=true;
      //2.设置标题
      this.dialogStatus="create"
      //3.清空表单元素的值
      this.resetMenu()
    },
    //清空
    resetMenu() {
      this.addForm = {
        id: undefined,
        url: '',
        path: null,
        component: null,
        name: '',
        iconCls: '',
        enabled: 1,
        menuLevel: 1,
        parentId: 0
      }
    },
    popoverHide(checkedIds,checkedData){
      this.addForm.parentId=checkedData.id;
    },
    selected(name){
      this.addForm.iconCls=name
    },
    insertData(){
      saveMenu(this.addForm)
        .then((res)=>{
          //1.关闭模态框
          this.addRightDialogVisible=false;
          if(res.code==200){
            //2.友好提示
            this.$message({
              title: '提示',
              message: res.message,
              type: 'success',
              duration: 2000
            })
            //3.刷新列表
            this.getMenusList()
          }else{
            //2.友好提示
            this.$message({
              title: '提示',
              message: res.message,
              type: 'error',
              duration: 2000
            })
          }
        })
        .catch((err)=>{
          console.log(err)
        })
    },
    showEditDialog(id){
        //1.打开模态框
        this.addRightDialogVisible = true
        //2.设置标题
        this.dialogStatus="update"
        //3.重置表单项
        this.resetMenu()

        //4.发送ajax请求查询数据
        findByMenuId(id)
          .then((res)=>{
            this.addForm=res;
            this.defaultCheckedKeys=[res.parentId]
          })
          .catch((err)=>{
            console.log(err)
          })
    },
    updateData(){
      updateMenu(this.addForm)
        .then((res)=>{
          //1.关闭模态框
          this.addRightDialogVisible=false;
          if(res.code==200){
            //2.友好提示
            this.$message({
              title: '提示',
              message: res.message,
              type: 'success',
              duration: 2000
            })
            //3.刷新列表
            this.getMenusList()
          }else{
            //2.友好提示
            this.$message({
              title: '提示',
              message: res.message,
              type: 'error',
              duration: 2000
            })
          }
        })
        .catch((err)=>{
          console.log(err)
        })
    },
    delRightById(id){
      this.$confirm(
      '确定要删除当前菜单吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then((res) => {
        delMenuById(id).then((res) => {
          if(res.code==200){
            //1.友好提示
            this.$message.success(res.message)
            //2.刷新列表
            this.getMenusList();

            // 删除菜单权限成功后，获取最新的菜单列表信息，并把它保存到Vuex中
            this.$store.dispatch('menu/initRouters').then((data) => {
              // 将fmtRouters添加router路由中，即保存到router/index.js中
              this.$router.addRoutes(data) // 动态添加路由
            }).catch((err) => {
              console.log(err)
            })
          }else{
            //1.友好提示
            this.$message.error(res.message)
          }
        }).catch((err) => {
          console.log(err)
        })
    }).catch(() => {
      return this.$message.info('您取消了删除！')
    })


    }
  } // 如果页面有keep-alive缓存功能，这个函数会触发
}
</script>
<style scoped>

</style>
